package com.kitty.game.role.service;

import com.kitty.common.bean.PayGateWay;
import com.kitty.common.db.Db4CommonService;
import com.kitty.common.mysql.DataSource;
import com.kitty.common.mysql.DataSourceType;
import com.kitty.common.utils.ConcurrentHashSet;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.ServerService;
import com.kitty.game.config.LoginServer;
import com.kitty.game.role.model.Account;
import com.kitty.game.role.model.AccountLogin;
import com.kitty.game.role.model.Invite;
import com.kitty.game.role.model.RoleSimple;
import com.kitty.game.utils.JsonUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.http.Request;
import org.nutz.http.Response;
import org.nutz.http.Sender;
import org.nutz.lang.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AccountService {
    Logger logger = LoggerFactory.getLogger(AccountService.class);

    @Autowired
    Dao dao;
    @Autowired
    JdbcTemplate jdbcTemplate;

    private static final ConcurrentHashSet<String> banned = new ConcurrentHashSet<>();

    @Cacheable(value = "account", key = "#id")
    public Account getAccount(String id) {
        //兼容假人没有账号登录情况。
        if(id.startsWith("ww")){
            Account account = new Account();
            account.setId(id);
            account.setIsStop(0);
            account.setPrivilege((short)0);
            return account;
        }else{
            Account account = dao.fetch(Account.class, Cnd.where("id", "=", id));
            if(account!=null){
                account.doAfterInit();
            }
            return account;
        }

    }
    @DataSource(value= DataSourceType.SLAVE)
    public Account getAccountNoCache(String id) {
        //兼容假人没有账号登录情况。
        if(id.startsWith("ww")){
            Account account = new Account();
            account.setId(id);
            account.setIsStop(0);
            account.setPrivilege((short)0);
            return account;
        }else{
            Account account = dao.fetch(Account.class, Cnd.where("id", "=", id));
            return account;
        }
    }
    public void getStopAccount() {
        List<Account> accounts = dao.query(Account.class, Cnd.where("isStop", "=", 1));
        for (Account account : accounts) {
            banned.add(account.getUsername());
        }
    }



    @CachePut(value = "account", key = "#account.id")
    public Account addAccount(Account account) {
        Db4CommonService.getInstance().add2Queue(account);
        return account;
    }

    @DataSource(value= DataSourceType.SLAVE)
    public AccountLogin queryAccount(String id) {
        if(id.startsWith("ww")){
            AccountLogin account = new AccountLogin();
            account.setId(id);
            account.setIsStop(0);
            account.setPrivilege((short)0);
            return account;
        }else{
            AccountLogin account = dao.fetch(AccountLogin.class, Cnd.where("id", "=", id));
            return account;
        }
    }

    @DataSource(value= DataSourceType.SLAVE)
    public int countPayGateway(String username) {
        return dao.count(PayGateWay.class, Cnd.where("account", "=", username));
    }

    //    @DataSource(value= DataSourceType.SLAVE)
//    public Invite queryInvite(String inviteAccount,String account){
//        Invite invite = dao.fetch(Invite.class, Cnd.where("inviteAccount", "=", inviteAccount)
//                .and("account", "=", account).and("rmb","=",0));
//        return invite;
//    }
    @DataSource(value= DataSourceType.SLAVE)
    public void updateInvite(Invite invite) {
        dao.update(invite, "state|updatetime");
    }

    @DataSource(value= DataSourceType.SLAVE)
    public List<Invite> queryInviteList(String inviteAccount) {
        List<Invite> list = dao.query(Invite.class, Cnd.where("inviteAccount", "=", inviteAccount).and("state", "=", 0));
        return list;
    }

    @DataSource(value= DataSourceType.SLAVE)
    public void update(Sql sql) {
        dao.execute(sql);
    }

    @DataSource(value= DataSourceType.SLAVE)
    public Invite fetchInvite(String username) {
        return dao.fetch(Invite.class, Cnd.where("account", "=", username).and("rmb", "=", 0).and("state", "=", 1));
    }

    @DataSource(value= DataSourceType.SLAVE)
    public int countInvite(String username) {
        return dao.count(Invite.class, Cnd.where("inviteAccount", "=", username).and("rmb", "=", 0).and("state", "=", 1));
    }

    @DataSource(value= DataSourceType.SLAVE)
    public int countInvite(String username, String start, String end) {
        return dao.count(Invite.class, Cnd.where("inviteAccount", "=", username).and("rmb", "=", 0).and("state", "=", 1).and("createtime", ">", start).and("createtime", "<", end));
    }


    @DataSource(value= DataSourceType.SLAVE)
    public void insertInvite(Invite invite) {
        dao.insert(invite);
    }

    @DataSource(value= DataSourceType.SLAVE)
    public List<LoginServer> queryServer() {
        return dao.query(LoginServer.class, Cnd.NEW());
    }

    @DataSource(value= DataSourceType.SLAVE)
    public AccountLogin queryByUsername(String username) {
        return dao.fetch(AccountLogin.class, Cnd.where("username", "=", username));
    }

    @DataSource(value= DataSourceType.SLAVE)
    public void updateAccount(AccountLogin accountLogin, String content) {
        if (content == null) {
            dao.update(accountLogin, "pwd|superPass");
        } else {
            dao.update(accountLogin, content);
        }
    }

    @DataSource(value= DataSourceType.SLAVE)
    public List<PayGateWay> getPayGateWay(String account) {
        String name = SpringUtils.getBean(ServerService.class).getServer().getName();
        return dao.query(PayGateWay.class, Cnd.where("account", "=", account).and("state", "=", 0).and("servername","=",name));
    }

    @DataSource(value= DataSourceType.SLAVE)
    public List<PayGateWay> getAllPayGateWay() {
        String name = SpringUtils.getBean(ServerService.class).getServer().getName();
        return dao.query(PayGateWay.class, Cnd.where("servername","=",name).and("state" ,"=","0"));
    }

    @DataSource(value= DataSourceType.SLAVE)
    public void update(PayGateWay payGateWay) {
        dao.update(payGateWay, "state");
    }


    /**
     * 查询设备是否在黑名单
     */
    public boolean isBanedDevice(String deviceInfo) {
        return banned.contains(deviceInfo);
    }
    /**
     * 查询账号是否在黑名单
     */
    public boolean isBanedPhone(String phone) {
        return banned.contains(phone);
    }
    /**
     * 添加黑名单账号
     */
    public void addBanedPhone(String phone) {
        banned.add(phone);
    }

    /**
     * 添加黑名单设备
     */
    public void addBanedDevice(String deviceInfo) {
        banned.add(deviceInfo);
    }
    /**
     * 移除黑名单账号
     */
    public void delBanedPhone(String phone) {
        banned.remove(phone);
    }

    /**
     * 移除黑名单设备
     */
    public void delBanedDevice(String deviceInfo) {
        banned.remove(deviceInfo);
    }


    /**
     * 查询IP是否在黑名单
     */
    public boolean isBanedIP(String ipAddr) {
        return banned.contains(ipAddr);
    }

    /**
     * 添加黑名单设备
     */
    public void addBanedIP(String ipAddr) {
        banned.add(ipAddr);
    }


    /**
     * 从登录服取一下帐号是否存在 取回代理号就行
     */
    public Map<String, Object> fetchAccountFromLoginServer(String sid) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", sid);
        Request request = Request.create(SpringUtils.getBean(ServerService.class).getLoginServerUrl() + "/login/fetch", Request.METHOD.POST).setParams(params);
        Response response = Sender.create(request).setTimeout(3000).send();
        if (!Strings.isEmpty(response.getContent())) {
            return JsonUtils.string2Map(response.getContent());
        }
        return null;
    }

    //**从登录服验证黑名单信息*//
    public boolean isBanned(String id, String ip, String mac) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("id", id);
            params.put("ip", ip);
            params.put("mac", mac);
            Request request = Request
                    .create(SpringUtils.getBean(ServerService.class).getLoginServerUrl() + "/login/banned",
                            Request.METHOD.POST)
                    .setParams(params);
            Response response = Sender.create(request).setTimeout(3000).send();
            if (!Strings.isEmpty(response.getContent())) {
                logger.error("从登录服验证黑名单信息=={}", response.getContent());
                return JsonUtils.string2Object(response.getContent(), Boolean.class);
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    public Account getAccountByUsername(String name) {
        Account account = dao.fetch(Account.class, Cnd.where("username", "=", name));
        if (account != null) {
            account.doAfterInit();
        }
        return account;
    }
    @DataSource(value= DataSourceType.SLAVE)
    public List<Account> queryAllAccount(Map<String, Object> data) {
        int pageNumber = Integer.parseInt(data.get("pageNum").toString());
        int pageSize = Integer.parseInt(data.get("pageSize").toString());
        List<Account> account = new ArrayList<>();
        if(data.containsKey("name") && data.containsKey("privilege")){
            String name = data.get("name").toString();
            String privilege = data.get("privilege").toString();
            account= dao.query(Account.class,Cnd.where("username","like","%"+name+"%").and("privilege","=",privilege),new Pager(pageNumber,pageSize));
        }else{
            if(data.containsKey("name") ) {
                String name = data.get("name").toString();
                account = dao.query(Account.class,Cnd.where("username","like","%"+name+"%"),new Pager(pageNumber,pageSize));
            }else if(data.containsKey("privilege")){
                String privilege = data.get("privilege").toString();
                account = dao.query(Account.class,Cnd.where("privilege","=",privilege),new Pager(pageNumber,pageSize));
            }else{
                account = dao.query(Account.class,Cnd.NEW(),new Pager(pageNumber,pageSize));
            }
        }

        return account;
    }
    /**
     * 查询账号下 角色
     * @param sid
     * @return
     */
    @DataSource(value= DataSourceType.SLAVE)
    public List<RoleSimple> getPlayerBySid(String sid,int pageNumber,int pgeSize) {
        List<RoleSimple> roles = dao.query(RoleSimple.class, Cnd.where("sid", "=", sid),new Pager(pageNumber,pgeSize));
        return roles;
    }
    @DataSource(value= DataSourceType.SLAVE)
    public Integer queryAccountCount(Map<String, Object> data) {
        int pageNumber = Integer.parseInt(data.get("pageNum").toString());
        int pageSize = Integer.parseInt(data.get("pageSize").toString());
        int count = 0;
        if(data.containsKey("name") && data.containsKey("privilege")){
            String name = data.get("name").toString();
            String privilege = data.get("privilege").toString();
            count= dao.count(Account.class,Cnd.where("username","like","%"+name+"%").and("privilege","=",privilege));
        }else{
            if(data.containsKey("name") ) {
                String name = data.get("name").toString();
                count = dao.count(Account.class,Cnd.where("username","like","%"+name+"%"));
            }else if(data.containsKey("privilege")){
                String privilege = data.get("privilege").toString();
                count = dao.count(Account.class,Cnd.where("privilege","=",privilege));
            }else{
                count = dao.count(Account.class);
            }
        }
        return count;
    }

    public Integer queryRoletCount(String sid) {
        Integer  count = dao.count(RoleSimple.class,Cnd.where("sid", "=", sid));
        return count;
    }


}
